package ldh.text.controller;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.IndexRange;
import javafx.scene.layout.*;
import ldh.text.controller.segment.DataControlPaneController;
import ldh.text.controller.segment.FindPaneController;
import ldh.text.controller.segment.TextStatusPaneController;
import ldh.text.service.CursorDataService;
import ldh.text.util.ThreadPoolUtil;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.LineNumberFactory;
import org.fxmisc.richtext.StyleClassedTextArea;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.nio.ByteBuffer;
import java.util.ResourceBundle;

public class BigDataTextAreaController implements Initializable {

    private static final Logger LOGGER = LoggerFactory.getLogger(BigDataTextAreaController.class);

    private VirtualizedScrollPane virtualizedScrollPane;
    private StyleClassedTextArea textArea;

    @FXML private StackPane textAreaContainer;
    @FXML private DataControlPaneController dataControlPaneController;
    @FXML private TextStatusPaneController textStatusPaneController;
    @FXML private FindPaneController findPaneController;

    private CursorDataService<ByteBuffer> dataService;
    private int cacheSize;
    private int moreNextSize;


    public void setDataService(CursorDataService cacheDataService, int cacheSize, int moreNextSize, int findMaxSize) {
        this.dataService = cacheDataService;
        this.cacheSize = cacheSize;
        this.moreNextSize = moreNextSize;

        dataControlPaneController.setDataService(cacheDataService, cacheSize, moreNextSize);
        dataControlPaneController.setTextArea(textArea);

        findPaneController.setTextArea(textArea,findMaxSize);
        findPaneController.setTextStatusPaneController(textStatusPaneController);
    }

    public void loadData(boolean isWrapText) {
        textArea.setWrapText(isWrapText);
        ThreadPoolUtil.submit(()->{
            try {
                ByteBuffer data = dataService.loadData(0, cacheSize);
                if (data.limit() < 1) return;
                String content = new String(data.array(), 0, data.limit(), "utf8");
                Platform.runLater(()->{
                    dataControlPaneController.setDataSize(dataService.dataSize());
                    textArea.insertText(0, content);
                });
            } catch (Exception e) {
                LOGGER.error("open file error", e);
            }
        });
    }

    public void setWrapText(boolean isWrap) {
        int currentParagraph = textArea.getCurrentParagraph();
        IndexRange indexRange = textArea.getSelection();

        textArea.setWrapText(isWrap);
        if (isWrap) {
            String text = textArea.getContent().getText();
            textArea.clear();
            textArea.insertText(0, text);
            textArea.showParagraphAtTop(currentParagraph);
            textArea.selectRange(indexRange.getStart(), indexRange.getEnd());
        }
    }

    public String getText() {
        return textArea.getText();
    }

    public void focus() {
        textArea.requestFocus();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        textArea = new StyleClassedTextArea();
        textArea.setParagraphGraphicFactory(LineNumberFactory.get(textArea));
        textArea.getStyleClass().add("text-area");
        virtualizedScrollPane = new VirtualizedScrollPane(textArea);
        textAreaContainer.getChildren().clear();
        textAreaContainer.getChildren().add(virtualizedScrollPane);
    }
}
